<?php


namespace app\api\controller\v14;


use app\common\lib\Aes;
use app\common\lib\exception\ApiException;
use app\common\lib\IAuth;
use app\common\lib\SensorsData;
use app\common\lib\Util;
use app\common\model\User;
use app\common\model\UserPush;
use GuzzleHttp\Client;
use think\Cache;
use think\Controller;
use think\Db;
use think\Log;

/**@version 1.9.8
 * Class Mobile
 * @package app\api\controller\v14
 */
class Mobile extends Controller
{

    public function login()
    {
        #神策打点 5   登录成功
        $sensorsTrackData = [
            'is_register' => false,
            'login_type' => '手机号一键登录',// 手机号、微信、QQ、微博、AppleID、手机号一键登录
            'is_temporary' => false,// 三方登录时，需要设置这个属性，是否为使用临时手机号验证
            'is_success' => true,
            'failed_reson' => '',
        ];
        $distinctId = $this->request->header('distinct-id', '');
        $loginToken = input('login_token/s');

        $res = $this->JGtokenGetMobile($loginToken);

        $time = $this->request->time();
        $ip = $this->request->ip();
        $appConfig = config('app');

        if ($res['success'])
        {
            $mobile = $res['mobile'];
            // 手机号不可注册
            $user = Util::CheckUserTel($mobile);
            // 生成token  和 token到期时间
            $token = IAuth::setAppLoginToken($mobile);
            $data = [
                'token' => $token,
                'token_expire' => strtotime("+" . $appConfig['login_time_out_day'] . " days"),
            ];
            $UserModel = new User();
            //判断用户是否绑定准了号
            if ($user)
            {
                $UserModel->check_uen($user);
            }

            $nickname = preg_replace('/(1[3456789]{1}[0-9])[0-9]{4}([0-9]{4})/i', '$1****$2', $mobile);
            $isRegist = false;
            // 该用户是否正常  forbidden==1 禁止登录
            if ($user && $user['forbidden'] == 0)
            {
                // 已过期重新生成access_token
                if ($time > $user['token_expire'] || !in_array($mobile, $appConfig['mobile']))
                {
                    $UserModel->where('tel', $mobile)->update($data);
                } else
                {
                    $token = $user['token'];
                }
//            $UserModel->save($data, ['tel' => $mobile]);
                if (!$user['nickname'])
                {
                    try
                    {
                        Db::table('app_user')->where('tel', $mobile)->update(['nickname' => $nickname]);
                    }
                    catch (Exception $e)
                    {
                        Log::write($mobile . '手机验证码登陆时初始化用户昵称失败' . $e->getMessage(), 'error', true);
                    }
                }
            } elseif ($user && $user['forbidden'] == 1)
            {
                if ($distinctId)
                {
                    $sensorsTrackData['is_success'] = false;
                    $sensorsTrackData['failed_reson'] = '该账号禁止登录';
                    SensorsData::track($user['id'], true, 'LoginSuccess', $sensorsTrackData);
                }

                return show(config('code.error'), '该账号禁止登录');
            } //手机号不可注册
            elseif (!$user && !empty($mobile))
            {
                $sensorsTrackData['is_register'] = true;
                $checkResult = Util::registCheckLogoutCD(['tel' => $mobile]);
                if (!$checkResult['result'])
                {
                    if ($distinctId)
                    {
                        $sensorsTrackData['is_success'] = false;
                        $sensorsTrackData['failed_reson'] = '账号注销时间不足，注册失败';
                        SensorsData::track($distinctId, false, 'LoginSuccess', $sensorsTrackData);
                    }
                    throw new ApiException($checkResult['msg'], 200, config('code.error'));
                }
                $isRegist = true;
                // 第一次登录 注册数据
                $user['uen'] = substr(md5($this->request->time(true) . mt_rand(0, 1000000) . uniqid('', true)), 0, 12);
                $user['nickname'] = $nickname;
                $user['reg_time'] = $time;
                $user['reg_ip'] = $ip;
                $user['last_login'] = $time;
                $user['last_ip'] = $ip;
                $user['last_active'] = $time;
                $user['status'] = 1;
                $user['sex'] = 1;
                $user['tel'] = $mobile;
                $user['is_first_login'] = 1;
                $user['uc_id'] = md5($mobile . $this->request->time(true));
                $user['token'] = $data['token'];
                $user['token_expire'] = $data['token_expire'];
                $user['has_self_recode'] = 0;
                $user['channel'] = Util::getChannelId();
                try
                {
                    $user['id'] = $UserModel->insertGetId($user);
                    Cache::set('user_total_amount_' . $user['id'], 0, 86400);// 消费金额为0
                    // 记录注册日志
                    Util::logRealTimeAnalyzeWrite(1, [
                        'user_uid' => $user['id'],
                        'user_name' => $mobile,
                        'user_sex' => 0,
                        'user_reg_type' => 5,//1微信 2QQ 3微博 4手机号 5一键登录
                        'user_ip' => $ip
                    ]);
                }
                catch (\Exception $e)
                {
                    if ($distinctId)
                    {
                        $sensorsTrackData['is_success'] = false;
                        $sensorsTrackData['failed_reson'] = '账号注销时间不足，注册失败';
                        SensorsData::track($user['id'], true, 'LoginSuccess', $sensorsTrackData);
                    }
                    return show(config('code.error'), '注册失败,请稍后重试');
                }
                if ($distinctId)
                {
                    // 用户完成手机号注册时，更新用户属性
                    $userData = [
                        'user_resgistration_time' => date('Y-m-d H:i:s', $user['reg_time']),
                        'user_uen' => $user['uen'],
                        'user_phone_num' => $user['tel'],
                        'user_is_vip' => false,
                        'user_vip_level' => 0,
                        'user_star_num' => 0
                    ];
                    SensorsData::profile($user['id'], true, $userData, 'set');
                }

                // 判断用户 APP版本大于等于 2.4.0 赠送 新手礼包
                if (Util::CheckAppVersion('2.4.0') !== '小')
                {   // 不小于 2.4.0
                    Util::queuePush('register_package', ['uid' => (int)$user['id']], 0);
                }

                try
                {
                    $msg = Db::table('app_message_center')->field('id')->where('range', 0)->select();
                }
                catch (\Exception $e)
                {
                    Log::write($mobile . '获取系统消息失败' . $e->getMessage(), 'error', true);
                }
                foreach ($msg as $k => $v)
                {
                    Db::table('app_user_msg')->insert(['uid' => $user['id'], 'mid' => $v['id']]);
                }
            }

            if ($user)
            {
                $id = (int)$user['id'];

                if (!$isRegist)
                {
                    $userPush = (new UserPush())->getUserRegid($id);
                    $calendarBirthdayStatus = (int)($userPush['calendar_birthday_status'] ?? 0);
                    $recodePrivateStatus = (int)($userPush['recode_private_status'] ?? 0);
                    $isLoginRecord = 1;
                } else
                {
                    $calendarBirthdayStatus = 1;
                    $recodePrivateStatus = 1;
                    $isLoginRecord = (int)($user['is_login_record'] ?? 1);  // 是否记录设备登陆历史 1=>记录，2=>不记录
                }

                // 记录登陆设备日志
                Util::loginRecordSave($id, 6, $isLoginRecord, $ip);

                if (isset($user['young_pwd']))
                {
                    $isYoung = $user['young_pwd'] ? true : false;
                } else
                {
                    $isYoung = false;
                }

                $result = [
                    'id' => $id,
                    'has_self_recode' => $user['has_self_recode'],
                    'user_access_token' => (new Aes())->encryptWithOpenssl($token . "||" . $user['id']),
                    'uc_id' => $user['uc_id'],
                    'calendar_birthday_status' => $calendarBirthdayStatus ?: 1,   // 在天象日历中展示生日信息
                    'recode_private_status' => $recodePrivateStatus ?: 1,   // 在星盘中展示档案详细信息
                    'has_bind_tel' => 1,     // 是否绑定了手机号 1绑定了 0未绑定
                    'is_young_model' => $isYoung ? 1 : 2,
                ];
                // 记录登陆日志
                Db::table('app_login_log')->insertGetId([
                    'uid' => $user['id'],
                    'login_time' => $time,
                    'login_type' => 6, // 6手机号一键登录
                    'login_ip' => $ip,
                ]);
                if ($distinctId)
                {
                    // 神策打点，用户关联
                    SensorsData::signup($id, $distinctId);
                    SensorsData::track($user['id'], true, 'LoginSuccess', $sensorsTrackData);
                }
                return show(config('code.success'), 'ok', $result);
            }
            if ($distinctId)
            {
                $sensorsTrackData['is_success'] = false;
                $sensorsTrackData['failed_reson'] = '一键登录失败';
                SensorsData::track($distinctId, false, 'LoginSuccess', $sensorsTrackData);
            }
            return show(config('code.error'), '登录失败');
        } else
        {
            if ($distinctId)
            {
                $sensorsTrackData['is_success'] = false;
                $sensorsTrackData['failed_reson'] = '一键登录失败';
                SensorsData::track($distinctId, false, 'LoginSuccess', $sensorsTrackData);
            }
            return show(411, '一键登录失败');
        }
    }

    /**
     * 极光通过code获取手机号
     * @param string $loginToken
     * @return array
     * @throws \GuzzleHttp\Exception\GuzzleException
     */
    private function JGtokenGetMobile(string $loginToken)
    {
        $url = 'https://api.verification.jpush.cn/v1/web/loginTokenVerify';
        $config = config('jpush');

        try
        {
            $client = new Client();
            // 获取图片信息
            $request = $client->request('POST', $url, [
                'json' => [
                    'loginToken' => $loginToken,
                ],
                'verify' => false,
                'headers' => [
                    'Accept' => 'application/json',
                    'Authorization' => 'Basic ' . base64_encode($config['app_key'] . ':' . $config['master_secret'])
                ]
            ]);
        }
        catch (\Exception $e)
        {
            Log::write("一键登录失败：错误行数{$e->getLine()},错误消息{$e->getMessage()}");
            return [
                'success' => false,
                'mobile' => '',
                'message' => $e->getMessage()
            ];
        }

        $httpCode = $request->getStatusCode();
        $result = $request->getBody()->getContents();
        $data = json_decode($result, true);
        if ($httpCode === 200 && $data['code'] === 8000)
        {
            $res = openssl_private_decrypt(base64_decode($data['phone']), $mobile, openssl_pkey_get_private($config['login_prikey']));

            if ($res)
            {
                return [
                    'success' => true,
                    'mobile' => $mobile,
                    'message' => '获取一键登录的手机号码成功'
                ];
            } else
            {
                Log::write(date('Y-m-d H:i:s') . '-键登录获取手机号解密失败！,' . $result, 'error', true);
                return [
                    'success' => false,
                    'mobile' => '',
                    'message' => '手机号解密失败，' . $result
                ];
            }
        } else
        {
            Log::write(date('Y-m-d H:i:s') . '手机号一键登录失败，错误信息' . $result . '；错误码信息【http://docs.jiguang.cn/jverification/server/rest_api/code_description/】', 'error', true);
            return [
                'success' => false,
                'mobile' => '',
                'message' => $result
            ];
        }
    }
}
